package com.macllvm.whale.model;

import android.os.Handler;
import android.os.Message;
import android.widget.RadioButton;
import android.util.Log;
import android.content.Context;
import java.util.LinkedList;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.nio.channels.SocketChannel;
import java.util.Observable;
import java.util.concurrent.atomic.AtomicInteger;
import com.macllvm.whale.entity.Transfer;
import com.macllvm.whale.net.TCPFileSendTask;


public class TransferOutManager  extends  Observable implements IProgressCallback{
    private LinkedList<Transfer> transferList = new LinkedList<Transfer>();
    private LinkedList<FutureTask<Integer>> sendTaskList = new LinkedList<FutureTask<Integer>>();
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private ExecutorService  executorService;
    private AtomicInteger fileId = new AtomicInteger(10000);

    public TransferOutManager() {
        executorService = Executors.newSingleThreadExecutor();
    }

    public void add(Transfer t){
        Lock l = lock.writeLock();
        l.lock();
        try{
            t.index = transferList.size();
            transferList.add(t);
            this.setChanged();
            this.notifyObservers();
        }finally {
            l.unlock();
        }
    }

    public Transfer getTansferById(int id){
        Transfer t = null;
        Lock l = lock.readLock();
        l.lock();
        try{

            int count = transferList.size();
            for(int i =0; i < count; i++){
                t = transferList.get(i);
                if( t.fileId == id){
                    break;
                }
            }
        }finally {
            l.unlock();
        }
        return t;
    }

    public int getSendFileId() {
        return fileId.addAndGet(1);
    }

    public LinkedList<Transfer> getDataSource() {
        return transferList;
    }

    public LinkedList<FutureTask<Integer>> getTaskList() {
        return sendTaskList;
    }

    public void startSendTask(SocketChannel channel){
        TCPFileSendTask task = new TCPFileSendTask(channel, this);
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Lock l = lock.writeLock();
        l.lock();
        try {
            if(sendTaskList.size() > 0)
                sendTaskList.remove(0);
            sendTaskList.add(futureTask);
            this.setChanged();
            this.notifyObservers();
        }finally {
            l.unlock();
        }
        executorService.submit(futureTask);
    }

    public void stopTask(int index){
        Lock l = lock.readLock();
        l.lock();
        try{
            if(transferList.get(index).percent < 100 ) {
                if(sendTaskList.size() > 0)
                    sendTaskList.get(0).cancel(true);
                transferList.get(index).state = Transfer.STATE_CANCEL;
                this.setChanged();
                this.notifyObservers();
            }
        }finally {
            l.unlock();
        }
    }

    public void stopAllTask() {
        executorService.shutdownNow();
    }

    @Override
    public void refreshProgress(int index){
        this.setChanged();
        this.notifyObservers(index);
    }

    @Override
    public Transfer getTransfer(int fileId){
        return getTansferById(fileId);
    }

}
